package com.platform.common.core.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.platform.common.core.annotation.EncryptField;

import java.lang.reflect.Field;

/**
 * 对象加解密工具
 * 其子类可以通过调用decryptField(T t)方法实现自加密，返回参数类型；
 * 调用encryptField(T t)实现自解密，返回参数类型；
 * encrypt对注解{@link EncryptField}字段有效；*
 */
public class EncryptUtil {

    /**
     * 秘钥
     */
    private static final String KEY = "CEUklPW9d3obte0jRfKy2g==";

    /**
     * 对含注解字段解密
     */
    public static <T> void decryptField(T t) {
        if (t == null) {
            return;
        }
        Field[] declaredFields = t.getClass().getDeclaredFields();
        try {
            if (declaredFields.length > 0) {
                for (Field field : declaredFields) {
                    if (field.isAnnotationPresent(EncryptField.class) && field.getType().toString().endsWith("String")) {
                        field.setAccessible(true);
                        String fieldValue = (String) field.get(t);
                        if (fieldValue != null && !"".equals(fieldValue.trim())) {
                            field.set(t, decryptStr(KEY, fieldValue));
                        }
                    }
                }
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 对含注解字段加密
     */
    public static <T> void encryptField(T t) {
        if (t == null) {
            return;
        }
        Field[] declaredFields = t.getClass().getDeclaredFields();
        try {
            if (declaredFields.length > 0) {
                for (Field field : declaredFields) {
                    if (field.isAnnotationPresent(EncryptField.class) && field.getType().toString().endsWith("String")) {
                        field.setAccessible(true);
                        String fieldValue = (String) field.get(t);
                        if (fieldValue != null && !"".equals(fieldValue.trim())) {
                            field.set(t, encryptHex(KEY, fieldValue));
                        }
                    }
                }
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 加密
     *
     * @param key     秘钥
     * @param content 加密内容
     * @return 加密字符串
     */
    private static String encryptHex(String key, String content) {
        // 构建
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, Base64.decode(key));
        // 加密为16进制表示
        return aes.encryptHex(content);
    }

    /**
     * 解密
     *
     * @param key        秘钥
     * @param encryptHex 要解密的密文
     * @return 解密后的明文
     */
    private static String decryptStr(String key, String encryptHex) {
        // 构建
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, Base64.decode(key));
        // 解密为字符串
        return aes.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
    }

    public static void main(String[] args) {
        String content = "test中文12121";

        // 随机生成密钥
        byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
        String encodeKey = Base64.encode(key);
        System.out.println("秘钥：" + encodeKey);

        String encryptHex = encryptHex(encodeKey, content);

        System.out.println("密文：" + encryptHex);
        System.out.println("明文：" + decryptStr(encodeKey, encryptHex));
    }
}
